5.02. Коллекции
Коллекции
Типы данных не всегда единичны, и порой их нужно перечислять в форме коллекции, собирая несколько элементов.
Последовательности — это упорядоченные коллекции элементов, доступные по индексу. К ним относятся строки (str), списки (list), кортежи (tuple), а также объекты range, bytes и другие. Все последовательности поддерживают общие операции: индексирование, срезы, конкатенацию, повторение и проверку на вхождение.
Базовые операции:
- Индексирование:
seq[i]— получение элемента по индексу (от 0). - Срезы:
seq[start:stop:step]— извлечение подпоследовательности. - Длина:
len(seq)— количество элементов. - Принадлежность:
x in seq— возвращаетTrue, если x содержится в последовательности. - Конкатенация:
seq1 + seq2— объединение (если типы совместимы). - Повторение:
seq * n— повторение последовательности n раз.
s = "hello"
print(s[1]) # 'e'
print(s[1:4]) # 'ell'
print('h' in s) # True
print(s * 2) # 'hellohello'
lst = [1, 2, 3]
print(lst + [4, 5]) # [1, 2, 3, 4, 5]
Циклы for естественно работают с последовательностями:
for item in [10, 20, 30]:
print(item)
Особенность строк — неизменяемость.
При попытке модификации через индекс возникнет TypeError. Для списков и кортежей это ограничение действует только для кортежей (они тоже неизменяемы). Но, собственно, давайте по порядку.
Коллекции — это типы данных, предназначенные для хранения упорядоченных или неупорядоченных множеств элементов. В языке Python коллекции реализованы как встроенные классы (встроенные типы), обеспечивающие различные семантики доступа, модификации и организации данных.
Основные встроенные коллекции включают:
list— список;tuple— кортеж;set— множество;dict— словарь.
Каждая из этих структур имеет свои особенности с точки зрения изменяемости, порядка элементов, уникальности и способов индексации. Выбор конкретной коллекции определяется требованиями к производительности, безопасности данных и логике алгоритма.
Списки (list).
Список — это упорядоченная, изменяемая коллекция элементов произвольных типов. Элементы списка хранятся последовательно и доступны по целочисленным индексам, начиная с нуля. Списки реализованы как динамические массивы с автоматическим управлением памятью.
Создание:
lst = [1, 2, 3]
Индексация и срезы.
Доступ к элементам осуществляется по индексу:
lst[0] # первый элемент
lst[-1] # последний элемент
Срезы позволяют извлекать подпоследовательности:
lst[1:3] # элементы с индексами 1 и 2
lst[::2] # каждый второй элемент
Срезы возвращают новый объект list. Они поддерживают шаг, отрицательные индексы и обратный порядок.
Списки имеют следующие методы:
append(x)- Добавляет элемент x в конец списка.extend(iterable)- Добавляет все элементы итерируемого объекта в конец.insert(i, x)- Вставляет элемент x на позицию i.remove(x)- Удаляет первое вхождение элемента x.pop([i])- Удаляет и возвращает элемент по индексу (по умолчанию — последний).count(x)- Возвращает количество вхождений элемента x.sort(key=None, reverse=False)- Сортирует список in-place.reverse()- Переворачивает список in-place.copy()- Создаёт поверхностную копию списка.
Примечание: методы sort и reverse модифицируют исходный объект и возвращают None.
Списки гетерогенны (могут быть разных типов), изменяемы (допускается добавление, удаление, замена элементов), и представляют собой массив указателей на объекты. При расширении происходит перераспределение памяти с запасом.
Бинарные списки: array.array используются для эффективного хранения числовых данных большого объёма. Этот тип представляет собой массив примитивных значений (например, целых или вещественных чисел) фиксированного размера.
import array
arr = array.array('i', [1, 2, 3]) # массив 32-битных целых
Такие списки занимают меньше памяти по сравнению с обычным списком, быстрее при последовательном доступе и поддерживают те же операции, что и списки (индексация, срезы), но только для однотипных данных. Но - не поддерживают гетерогенные данные.
Кортежи (tuple)
Кортеж — это упорядоченная, неизменяемая коллекция элементов произвольных типов. После создания кортеж нельзя модифицировать: нельзя добавлять, удалять или заменять элементы. Кортежи неизменяемые (чтобы гарантировать целостность данных), хэшируемые (сам кортеж может использовать в качестве ключа в словаре или элементе множества), производительны и применяются часто для представления составных данных, например, координат (x, y) или возврат нескольких значений из функции.
Пример:
t = (1, 2, 3)
t = 1, 2, 3 # скобки опциональны
Кортежи поддерживают ограниченный набор методов:
count(x)— количество вхождений элемента x.index(x[, start[, end]])— индекс первого вхождения x.
Поскольку кортежи неизменяемы, методы модификации отсутствуют.
Множества (set)
Множество — это неупорядоченная, изменяемая коллекция уникальных элементов. Элементы множества должны быть хэшируемыми (т.е. иметь метод __hash__ и быть сравнимыми).
Создание:
s = {1, 2, 3}
s = set([1, 2, 3]) # из итерируемого
Пустое множество создаётся только через set(), так как {} интерпретируется как пустой словарь.
Множества автоматически устраняют дубликаты:
{1, 1, 2} # → {1, 2}
Множества бывают изменяемыми и неизменяемыми.
Методы изменяемых множеств (set):
add(x)— добавить элемент.remove(x)— удалить элемент; ошибка, если нет.discard(x)— удалить, если есть; ошибки не возникает.pop()— удалить и вернуть произвольный элемент.clear()— очистить множество.
frozenset — неизменяемая версия множества. Поддерживает все операции чтения и теоретико-множественные операции, но не позволяет модифицировать содержимое. Полезен как ключ в словаре или элемент другого множества.
Словари (dict)
Словарь — это изменяемая коллекция пар «ключ-значение», где ключи уникальны и хэшируемы, а значения могут быть любыми объектами. Доступ к значениям осуществляется по ключу. Словари реализованы как хеш-таблицы с открытой адресацией.
Создание:
d = {'a': 1, 'b': 2}
d = dict(a=1, b=2)
Ключи должны быть хэшируемыми (числа, строки, кортежи из хэшируемых объектов и т.д.). Значения же произвольные объекты, включая изменяемые. Словари сохраняют порядок вставки с Python 3.7+ (в 3.6 — как особенность CPython, с 3.7 — как гарантия языка).
Методы словарей:
keys()- Итератор ключей;values()- Итератор значений;items()- Итератор пар (ключ, значение);get(key, default=None)- Значение по ключу или значение по умолчанию;pop(key, default)- Удаляет и возвращает значение; если ключа нет — возвращает default;update(other)- Обновляет словарь парами из другого словаря или итерируемого;setdefault(key, default)- Возвращает значение, если ключ есть; иначе устанавливает и возвращает default;clear()- Очищает словарь;copy()- Поверхностная копия.